/**
 * 作者: 会写BUG
 * 创作日期: 2025/3/31 19:05
 * 描述: cwbQtPractice.ScoreRecord
 *
 **/
#include "score_record.h"

#include <QApplication>
#include <QRandomGenerator>
#include <QRegularExpression>
#include <QFileInfo>

ScoreRecord * ScoreRecord::instance_ = nullptr;

ScoreRecord::ScoreRecord(QObject* _parent)
    : QObject(_parent)
{
    for (int index = 0; index < 16; ++index) {
        chess_numbers_ << 0;
    }
}

ScoreRecord::~ScoreRecord()
{
    if (!record_file_.isOpen()) {
        return;
    }
    record_stream_.flush();
    record_file_.close();
}

void ScoreRecord::setScore(int _score)
{
    score_ = _score;
    if (top_score_ < score_) {
        top_score_ = score_;
    }

    Q_EMIT chessChanged();
}

void ScoreRecord::setTopScore(int _score)
{
    top_score_ = _score;
}

int ScoreRecord::score() const
{
    return score_;
}

int ScoreRecord::topScore() const
{
    return top_score_;
}

void ScoreRecord::setChessNumber(int _index, int _number)
{
    if (_index < 0 || _index >= 16)
    {
        return;
    }
    chess_numbers_[_index] = _number;
}

QList<int> ScoreRecord::chessNumbers() const
{
    return chess_numbers_;
}

void ScoreRecord::resetChessNumber()
{
    for (int index = 0; index < 16; ++index) {
        chess_numbers_[index] = 0;
    }
}

void ScoreRecord::initRecord()
{
    QString record_file_path = QApplication::applicationDirPath() + "/records/cwb2048.sv";
    record_file_.setFileName(record_file_path);
    record_file_.open(QIODevice::ReadWrite | QIODevice::Truncate);
    record_stream_.setDevice(&record_file_);
    records_.clear();

    int index_1 = QRandomGenerator::global()->bounded(16);
    int index_2 = QRandomGenerator::global()->bounded(16);
    index_2 = index_1 == index_2 ? --index_2 : index_2;
    if (index_2 < 0)
    {
        index_2 = index_1 + 1;
    }

    int random_value = QRandomGenerator::global()->bounded(100);
    chess_numbers_[index_1] = random_value > 90 ? 4 : 2;
    random_value = QRandomGenerator::global()->bounded(100);
    chess_numbers_[index_2] = random_value > 90 ? 4 : 2;

}

void ScoreRecord::loadRecord()
{
    QString record_file_path = QApplication::applicationDirPath() + "/records/cwb2048.sv";
    record_file_.setFileName(record_file_path);
    record_file_.open(QIODevice::ReadWrite);
    record_stream_.setDevice(&record_file_);
    records_.clear();

    while (!record_stream_.atEnd()) {
        QString record = record_stream_.readLine();
        records_ << record;
    }

    resetRecord(records_.count() - 1);
}

int ScoreRecord::recordCount() const
{
    return records_.count();
}

void ScoreRecord::resetRecord(int _index)
{
    if (_index < 0 || _index >= records_.count()) {
        return;
    }

    QString record = records_[_index];
    /* 解析字符串内容 */
    /* 格式：
     *      score:0#top_score:0#chess:[0:0][1:0][2:0][3:0][4:0][5:2][6:0][7:0][8:0][9:0][10:0][11:0][12:2][13:0][14:0][15:0]
     */
    QRegularExpression record_regx(R"(^score:(\d+)#top_score:(\d+)#chess:(.*)$)");
    QRegularExpressionMatch record_match = record_regx.match(record);
    if (record_match.hasCaptured(1))
    {
        /* 捕获到上次记录的当前分数 */
        score_ = record_match.captured(1).toInt();
    }
    if (record_match.hasCaptured(2))
    {
        /* 捕获到上次记录的最高分数 */
        top_score_ = record_match.captured(2).toInt();
    }
    if (record_match.hasCaptured(3))
    {
        /* 捕获到上次全部棋盘位置 */
        QString chess_state = record_match.captured(3);
        /* 解析数字棋盘的位置 */
        QRegularExpression state_regx(R"(\[(\d+):(\d+)\])");
        QRegularExpressionMatchIterator state_regx_iter = state_regx.globalMatch(chess_state);
        while (state_regx_iter.hasNext())
        {
            QRegularExpressionMatch state_match = state_regx_iter.next();
            /* 位置 */
            int pos = state_match.captured(1).toInt();
            /* 数值 */
            int number = state_match.captured(2).toInt();
            chess_numbers_[pos] = number;
        }
    }
    Q_EMIT chessChanged();
}

bool ScoreRecord::hasRecord() const
{
    QString record_file_path = QApplication::applicationDirPath() + "/records/cwb2048.sv";
    QFileInfo file_info(record_file_path);
    if (!file_info.exists()) {
        return false;
    }

    QFile file(record_file_path);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }

    auto read_contexts = file.readAll();
    file.close();

    return !read_contexts.isEmpty();
}

void ScoreRecord::record()
{
    if (!record_file_.isOpen()) {
        return;
    }

    /* 格式化保存内容 */
    QString record_content = QString("score:%1#top_score:%2#chess:").arg(score_).arg(top_score_);
    for (int index = 0; index < 16; ++index) {
        record_content += QString("[%1:%2]").arg(index).arg(chess_numbers_[index]);
    }

    records_ << record_content;

    record_stream_ << record_content;
    record_stream_ << "\n";
    record_stream_.flush();
}

QPair<int, int> ScoreRecord::newChessPos() {
    /* 找到剩余位置 */

    auto residual_indexes = QList<int>();
    for (int index = 0; index < chess_numbers_.count(); ++index)
    {
        if (chess_numbers_[index] == 0)
            residual_indexes << index;
    }

    if (residual_indexes.isEmpty())
    {
        /* 没有剩余位置游戏结束 */
        return {};
    }

    int index = QRandomGenerator::global()->bounded(residual_indexes.count());
    index = residual_indexes[index];

    int random_value = QRandomGenerator::global()->bounded(100);
    chess_numbers_[index] = random_value > 90 ? 4 : 2;
    chess_numbers_.insert(index, chess_numbers_[index]);

    return qMakePair(index, chess_numbers_[index]);
}
